package configcenter

import (
	"cftgo/cftc"
	"cftgo/cftf/configcenter"
	"cftgo/cftf/logger/syslog"
	"os"
	"strings"
)

type MysqlClusterConf struct {
	InstanceId   uint32 `json:"instance_id"`
	Host         string `json:"host"`
	Port         int32  `json:"port"`
	User         string `json:"user"`
	Passwd       string `json:"passwd"`
	DataBase     string `json:"database"`
	MaxOpenConns int32  `json:"max_open_conns"`
	MaxIdleConns int32  `json:"max_idle_conns"`
}

type PublicKey struct {
	Kty string `json:"kty"`
	X   string `json:"x"`
	Y   string `json:"y"`
	Crv string `json:"crv"`
	Kid string `json:"kid"`
	Use string `json:"use"`
	Alg string `json:"alg"`
}

type config struct {
	BabyplanDb MysqlClusterConf
	PublicKeys *cftc.ConcurrentMap[string, PublicKey]
}

var instance = new(config)

func Init() {
	consulUrls := strings.Split(os.Getenv("ConsulUrls"), ";")
	if len(consulUrls) <= 0 || consulUrls[0] == "" {
		panic("consul_url not setting")
	}
	configcenter.SetConsulUrls(consulUrls)
	err, kvs := configcenter.GetValues("babyplan", map[string]string{
		"recurse": "true",
	})
	{
		val := ""
		if configcenter.FindAndDecodeValueByPath(kvs, "babyplan/db/babyplandb", &val) {
			if cftc.DecodeJson(val, &instance.BabyplanDb) == nil {
			} else {
				panic("configcenter parse babyplandb error")
			}
		} else {
			panic("configcenter read babyplandb error")
		}
	}
	if !readPublishKeys() {
		panic("configcenter read publish keys")
	}
	syslog.Info("configcenter.init %s %s", err, kvs)
}

func UnInit() {

}

func readPublishKeys() bool {
	err, kvs := configcenter.GetValues("public/certs/jwks", map[string]string{
		"recurse": "true",
	})
	if err != nil {
		return false
	}
	keys := new(cftc.ConcurrentMap[string, PublicKey])
	reqOjb := struct {
		Keys []PublicKey `json:"keys"`
	}{}
	for _, v := range kvs {
		if v.Key == "public/certs/jwks" {
			if deVal, err := v.DecodeValue(); err == nil {
				if cftc.DecodeJson(deVal, &reqOjb) == nil {
					for _, keyObj := range reqOjb.Keys {
						keys.Store(keyObj.Kid, keyObj)
					}
				} else {
					return false
				}
			} else {
				return false
			}
		}
	}
	instance.PublicKeys = keys
	return true
}

func GetBabyPlanDbConf() *MysqlClusterConf {
	return &instance.BabyplanDb
}

func GetPublishKey(key string) *PublicKey {
	if pubKey, ok := instance.PublicKeys.Load(key); ok {
		return pubKey
	} else {
		return nil
	}
}
